package com.shimba.recording.universalinterface.nblinterface;

import android.text.TextUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by Administrator on 2019/1/10.
 */

public class FunctionManager {
    private static FunctionManager instance;
    //创建不同类型的方法的容器
    private Map<String, FunctionNoParamNoResult> mNoParamNoResultMap;
    private Map<String, FunctionNoParamHasResult> mNoParamHasResultMap;
    private Map<String, FunctionHasParamNoResult> mHasParamNoResultMap;
    private Map<String, FunctionHasParamHasResult> mHasParamHasResultMap;

    private FunctionManager() {
        mNoParamNoResultMap = new HashMap<>();
        mNoParamHasResultMap = new HashMap<>();
        mHasParamNoResultMap = new HashMap<>();
        mHasParamHasResultMap = new HashMap<>();
    }

    //创建FunctionManager的单例
    public static FunctionManager getInstance() {
        if (instance == null) {
            instance = new FunctionManager();

        }
        return instance;
    }

    //将不同类型的方法对象，放入容器（Map） Key值为方法名

    /**
     * 添加没有参数，没有返回值的方法
     */

    public void addFunction(FunctionNoParamNoResult function) {
        mNoParamNoResultMap.put(function.functionName, function);
    }

    //执行没有参数，没有返回值的方法
    public void invokeFunction(String functionName) {
        if (TextUtils.isEmpty(functionName)) {
            return;
        }
        if (mNoParamNoResultMap != null) {
            FunctionNoParamNoResult f = mNoParamNoResultMap.get(functionName);
            if (f != null) {
                f.function();
            } else {
                try {
                    throw new FunctionNotFoundException("has no this function" + functionName);
                } catch (FunctionNotFoundException e) {
                    e.printStackTrace();
                }
            }

        }
    }

    /**
     * 添加没有参数，有返回值的方法
     */

    public void addFunction(FunctionNoParamHasResult function) {
        mNoParamHasResultMap.put(function.functionName, function);
    }

    //执行没有参数，有返回值的方法
    public <T> T invokeFunction(String functionName, Class<T> t) {
        if (TextUtils.isEmpty(functionName)) {
            return null;
        }
        if (mNoParamHasResultMap != null) {
            FunctionNoParamHasResult f = mNoParamHasResultMap.get(functionName);
            if (f != null) {
                if (t != null) {
                    //将一个对象转换为类或者接口
                    return t.cast(f.function());
                }

            } else {
                try {
                    throw new FunctionNotFoundException("has no this function" + functionName);
                } catch (FunctionNotFoundException e) {
                    e.printStackTrace();
                }
            }

        }
        return null;
    }

    /**
     * 添加有参数，没有返回值的方法
     */
    public void addFunction(FunctionHasParamNoResult function) {
        mHasParamNoResultMap.put(function.functionName, function);
    }

    //执行有参数，没有返回值的方法
    public <P> void invokeFunction(String functionName, P p) {
        if (TextUtils.isEmpty(functionName)) {
            return;
        }
        if (mHasParamNoResultMap != null) {
            FunctionHasParamNoResult f = mHasParamNoResultMap.get(functionName);
            if (f != null) {
                f.function(p);

            } else {
                try {
                    throw new FunctionNotFoundException("has no this function" + functionName);
                } catch (FunctionNotFoundException e) {
                    e.printStackTrace();
                }
            }

        }

    }

    /**
     * 添加有参数，有返回值的方法
     */
    public void addFunction(FunctionHasParamHasResult function) {
        mHasParamHasResultMap.put(function.functionName, function);
    }
    //执行有参数，有返回值的方法

    public <T, P> T invokeFunction(String functionName, P p, Class<T> t) {
        if (TextUtils.isEmpty(functionName)) {
            return null;
        }
        if (mHasParamHasResultMap != null) {
            FunctionHasParamHasResult f = mHasParamHasResultMap.get(functionName);
            if (f != null) {
                if (t != null) {
                    return t.cast(f.function(p));
                }
            } else {
                try {
                    throw new FunctionNotFoundException("has no this function" + functionName);
                } catch (FunctionNotFoundException e) {
                    e.printStackTrace();
                }
            }

        }
        return null;

    }
}

